home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / Snippets / Toolbox / Color Picker / Color Picker.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  6.6 KB  |  271 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    Color Picker Test                                        */
  4. /*                                                                            */
  5. /*    Description:    This application demonstrates how to use the color        */
  6. /*                    picker package to dynamically change colors in a        */
  7. /*                    custom palette.  The program basically displays 16        */
  8. /*                    squares, each representing a separate entry in the        */
  9. /*                    palette.  Clicking the mouse in any box allows the        */
  10. /*                    user to redefine that box's color with the color        */
  11. /*                    picker package routines.  The trap ActivatePalette        */
  12. /*                    is called after each color change to guarantee the        */
  13. /*                    window is updated with the palette changes.  Without    */
  14. /*                    this safeguard, random results may occur and the        */
  15. /*                    color change may not take affect until the window        */
  16. /*                    has physically changed or moved.  Finally, the first    */
  17. /*                    and last entries in the palette cannot be changed        */
  18. /*                    and are always defined to black and white.  This is        */
  19. /*                    done because ActivatePalette will only update 14        */
  20. /*                    non-b/w Tolerant colors.  The remaining 2 colors        */
  21. /*                    if defined as b/w will be updated, otherwise QD will    */
  22. /*                    return the color in the palette which is the closest    */
  23. /*                    match to the RGB values of these entries.                */    
  24. /*                                                                            */
  25. /*    File:            Color Picker.c                                            */
  26. /*                                                                            */
  27. /*    Programmer:        Edgar Lee                                                */
  28. /*    Organization:    Apple Computer, Inc.                                    */
  29. /*    Department:        Developer Technical Support, DTS                        */
  30. /*    Language:        C (Think C version 4.0.4)                                */
  31. /*    Date Created:    10-02-91                                                */
  32. /*                                                                            */
  33. /****************************************************************************/
  34.  
  35. #include <AppleEvents.h>
  36. #include <Errors.h>
  37. #include <Events.h>
  38. #include <Fonts.h>
  39. #include <GestaltEqu.h>
  40. #include <Memory.h>
  41. #include <Menus.h>
  42. #include <OSUtils.h>
  43. #include <QDOffscreen.h>
  44. #include <QuickDraw.h>
  45. #include <Resources.h>
  46. #include <Script.h>
  47. #include <ToolUtils.h>
  48. #include <Windows.h>
  49. #include <Palettes.h>
  50.  
  51. /* Constant Declarations */
  52.  
  53. #define    TOTALCOLORS    16
  54.  
  55. #define    BOXSIZE        75
  56. #define    WWIDTH        ((TOTALCOLORS / 4) * BOXSIZE)
  57. #define    WHEIGHT        ((TOTALCOLORS / 4) * BOXSIZE )
  58.  
  59. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  60. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  61.  
  62. /* Global Variable Definitions */
  63.  
  64. WindowPtr            gWindow;
  65. PaletteHandle        gPalette;
  66.  
  67. void initMac();
  68. void createWindow();
  69. void createPalette();
  70. void drawImage();
  71.  
  72. void doEventLoop();
  73. void doInContent();
  74.  
  75. main()
  76. {
  77.     initMac();
  78.     
  79.     createWindow();
  80.     createPalette();
  81.     drawImage();
  82.  
  83.     doEventLoop();
  84.  
  85.     DisposeWindow( gWindow );
  86. }
  87.  
  88. void initMac()
  89. {
  90.     MaxApplZone();
  91.  
  92.     InitGraf( &thePort );
  93.     InitFonts();
  94.     InitWindows();
  95.     InitMenus();
  96.     TEInit();
  97.     InitDialogs( nil );
  98.     InitCursor();
  99.     FlushEvents( 0, everyEvent );
  100. }
  101.  
  102. void createWindow()
  103. {
  104.     Rect wBounds;
  105.     
  106.     /* Create a window to display the image. */
  107.     
  108.     SetRect( &wBounds, WLEFT, WTOP, WLEFT + WWIDTH, WTOP + WHEIGHT );
  109.     
  110.     gWindow = NewCWindow( 0L, &wBounds, "\pColor Picker Test", true, documentProc,
  111.                             (WindowPtr)-1L, true, 0L );
  112.                             
  113.     ShowWindow( gWindow );
  114.     SetPort( gWindow );
  115. }
  116.  
  117. void createPalette()
  118. {
  119.     int    index;
  120.     RGBColor aColor;
  121.  
  122.     /* Create the palette of size TOTALCOLORS. */
  123.     
  124.     gPalette = NewPalette( TOTALCOLORS, nil, pmTolerant, 0 );
  125.     
  126.     /* Assign a color to the first 15 palette entries. */
  127.  
  128.     for (index = 0; index < (TOTALCOLORS - 1); index++)
  129.     {
  130.         aColor.blue = index * (0xffff / (TOTALCOLORS - 2));
  131.         aColor.red = aColor.green = 0;
  132.         SetEntryColor( gPalette, index, &aColor );
  133.     }
  134.     
  135.     /* Set the last entry to white. */
  136.     
  137.     aColor.red = aColor.green = aColor.blue = 0xffff;
  138.     SetEntryColor( gPalette, (TOTALCOLORS - 1), &aColor );
  139.  
  140.     /* Attach the new palette to the main window. */
  141.     
  142.     SetPalette( gWindow, gPalette, true );
  143. }
  144.  
  145. void drawImage()
  146. {
  147.     int            i;
  148.     int            x, y;
  149.     Rect        rect;
  150.     RGBColor    aColor;
  151.  
  152.     /* Draw a grid of colors to represent each color entry in the palette. */
  153.  
  154.     for (i = 0; i < TOTALCOLORS; i++)
  155.     {
  156.         x = (i % 4) * BOXSIZE;
  157.         y = (i / 4) * BOXSIZE;
  158.         
  159.         GetEntryColor( gPalette, i, &aColor );
  160.         RGBForeColor( &aColor );
  161.         
  162.         SetRect( &rect, x, y, x + BOXSIZE, y + BOXSIZE );
  163.         PaintRect( &rect );
  164.     }
  165. }
  166.  
  167. void doInContent( thePoint )
  168. Point thePoint;
  169. {
  170.     int            paletteIndex = -1;
  171.     Point        where;
  172.     RGBColor    currentColor, newColor;
  173.     Rect        rect;
  174.     int            ret;
  175.  
  176.     /* Get the palette entry index for the box drawn at the mouse click. */
  177.     
  178.     paletteIndex = ((thePoint.v / BOXSIZE) * 4) + (thePoint.h / BOXSIZE);
  179.     
  180.     /* If the paletteIndex isn't the first or last entry, do the following. */
  181.  
  182.     if (paletteIndex > 0 && paletteIndex < (TOTALCOLORS - 1))
  183.     {
  184.         /* Invert the selected box then beep the Mac. */
  185.     
  186.         SetRect( &rect, (paletteIndex % 4) * BOXSIZE,
  187.                     (paletteIndex / 4) * BOXSIZE,
  188.                     ((paletteIndex % 4) * BOXSIZE) + BOXSIZE,
  189.                     ((paletteIndex / 4) * BOXSIZE) + BOXSIZE );
  190.         InvertRect( &rect );
  191.         SysBeep( 1 );
  192.     
  193.         /* Get the RGB values for the color stored at this palette index. */
  194.         
  195.         GetEntryColor( gPalette, paletteIndex, ¤tColor );
  196.         
  197.         /* Open the color picker dialog to select new RGB values. */
  198.         
  199.         where.h = where.v = -1;
  200.  
  201.         if (GetColor( where, "\pSelect a new palette color.", ¤tColor, &newColor ))
  202.         {
  203.             /* Assign the new RGB values to this entry. */
  204.             
  205.             SetEntryColor( gPalette, paletteIndex, &newColor );
  206.             
  207.             /* Update the palette with the new colors. */
  208.             
  209.             ActivatePalette( gWindow );
  210.             
  211.             /* Redraw the image with the new palette colors. */
  212.         
  213.             drawImage();
  214.         }
  215.         else
  216.         {
  217.             /* Invert the rect back to its original state on a Cancel. */
  218.             
  219.             InvertRect( &rect );
  220.         }
  221.     }
  222. }
  223.  
  224. void doEventLoop()
  225. {
  226.     EventRecord anEvent;
  227.     WindowPtr   evtWind;
  228.     short       clickArea;
  229.     Rect        screenRect;
  230.     Point        thePoint;
  231.  
  232.     for (;;)
  233.     {
  234.         if (WaitNextEvent( everyEvent, &anEvent, 0, nil ))
  235.         {
  236.             if (anEvent.what == mouseDown)
  237.             {
  238.                 clickArea = FindWindow( anEvent.where, &evtWind );
  239.                 
  240.                 if (clickArea == inDrag)
  241.                 {
  242.                     screenRect = (**GetGrayRgn ()).rgnBBox;
  243.                     DragWindow( evtWind, anEvent.where, &screenRect );
  244.                 }
  245.                 else if (clickArea == inContent)
  246.                 {
  247.                     if (evtWind != FrontWindow())
  248.                         SelectWindow( evtWind );
  249.                     else
  250.                     {
  251.                         thePoint = anEvent.where;
  252.                         GlobalToLocal( &thePoint );
  253.                         doInContent( thePoint );
  254.                     }
  255.                 }
  256.                 else if (clickArea == inGoAway)
  257.                     if (TrackGoAway( evtWind, anEvent.where ))
  258.                         return;
  259.             }
  260.             else if (anEvent.what == updateEvt)
  261.             {
  262.                 evtWind = (WindowPtr)anEvent.message;    
  263.                 SetPort( evtWind );
  264.                 
  265.                 BeginUpdate( evtWind );
  266.                 drawImage();
  267.                 EndUpdate (evtWind);
  268.             }
  269.         }
  270.     }
  271. }